package cqrtplm.service.impl;

import com.ty.basic.entity.org.UserDO;
import com.ty.basic.exception.MessageException;
import com.ty.basic.service.snow.SnowflakeIdComponent;
import com.ty.basic.session.TyAccountContext;
import cqrtplm.constant.RTErrorCodeEnum;
import cqrtplm.dto.RTCertFiledFormDTO;
import cqrtplm.entity.RtCertFiledCustomerDO;
import cqrtplm.entity.RtCertFiledDO;
import cqrtplm.mapper.RtCertFiledCustomerMapper;
import cqrtplm.service.RtCertFiledCustomerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 备案客户信息服务实现
 */
@Service
@Slf4j
public class RtCertFiledCustomerServiceImpl implements RtCertFiledCustomerService {

    @Resource
    private RtCertFiledCustomerMapper rtCertFiledCustomerMapper;
    @Resource
    private RTLogDifferenceServiceImpl rtLogDifferenceService;
    @Resource
    private SnowflakeIdComponent snowflakeIdComponent;

    @Override
    public RtCertFiledCustomerDO selectRtCertFiledCustomerById(String id) {
        return rtCertFiledCustomerMapper.selectRtCertFiledCustomerById(id);
    }

    @Override
    public List<RtCertFiledCustomerDO> selectRtCertFiledCustomerList(RtCertFiledCustomerDO rtCertFiledCustomer) {
        return rtCertFiledCustomerMapper.selectRtCertFiledCustomerList(rtCertFiledCustomer);
    }

    @Override
    @Transactional
    public int insertRtCertFiledCustomer(RtCertFiledCustomerDO rtCertFiledCustomer) {
        List<RtCertFiledCustomerDO> old = rtCertFiledCustomerMapper.selectRtCertFiledCustomerByDO(rtCertFiledCustomer);
        if(old != null && !old.isEmpty()) {
            throw new MessageException("该认证、备案机型和客户的组合已存在，请勿重复添加");
            //throw RTErrorCodeEnum.CERT_FILED_EXISTS.getException("该认证、备案机型和客户的组合已存在，请勿重复添加");
        } else {
            UserDO user = TyAccountContext.getUser();
            if (user == null) {
                throw new RuntimeException("用户未登录");
            }

            String snowId = String.valueOf(snowflakeIdComponent.getInstance().nextId());
            Timestamp timestamp = new Timestamp(new Date().getTime());

            rtCertFiledCustomer.setId(snowId);
            rtCertFiledCustomer.setCreateTime(timestamp);
            rtCertFiledCustomer.setCreateUserId(String.valueOf(user.getOid()));
            rtCertFiledCustomer.setCreateUserName(user.getName());

            log.info("备案客户信息-新增{},{},{},{}",
                     rtCertFiledCustomer.getKhmc(),
                     snowId,
                     timestamp,
                     user.getName());

            return rtCertFiledCustomerMapper.insertRtCertFiledCustomer(rtCertFiledCustomer);
        }
    }

    @Override
    @Transactional
    public int updateRtCertFiledCustomer(RtCertFiledCustomerDO rtCertFiledCustomer) {
        RtCertFiledCustomerDO old = rtCertFiledCustomerMapper.selectRtCertFiledCustomerById(rtCertFiledCustomer.getId());
        if(old == null) {
            throw RTErrorCodeEnum.DATA_NOT_EXISTS.getException("该客户备案信息不存在，请检查");
        } else {
            UserDO user = TyAccountContext.getUser();
            if (user == null) {
                throw new RuntimeException("用户未登录");
            }

            Timestamp timestamp = new Timestamp(new Date().getTime());
            rtCertFiledCustomer.setUpdateTime(timestamp);
            rtCertFiledCustomer.setUpdateUserId(String.valueOf(user.getOid()));
            rtCertFiledCustomer.setUpdateUserName(user.getName());

            int r = rtCertFiledCustomerMapper.updateRtCertFiledCustomer(rtCertFiledCustomer);
            if(r > 0) {
                // 记录差异日志
                rtLogDifferenceService.newLog(
                        rtCertFiledCustomer, old,
                        rtCertFiledCustomer.getId(),
                        rtCertFiledCustomer.getCreateUserName(),
                        "备案客户信息",
                        "修改",
                        ""
                );
            }
            return r;
        }
    }

    @Override
    public void updateEntityList(RTCertFiledFormDTO formDTO, List<RtCertFiledCustomerDO> list) {
        String filedId = formDTO.getRtCertFiledDO().getId();
        // 获取数据库中现有的客户列表
        if(!list.isEmpty()){

            RtCertFiledCustomerDO q = new RtCertFiledCustomerDO();
            q.setFiledId(filedId);
            List<RtCertFiledCustomerDO> existingList = selectRtCertFiledCustomerList(q);

            // 获取数据库中所有存在的ID集合
            Set<String> existingIds = existingList.stream()
                    .map(RtCertFiledCustomerDO::getId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toSet());
            // 编辑操作进行增量处理

            // 1. 找出需要删除的记录（存在于数据库但不在新列表中）
            List<RtCertFiledCustomerDO> toDelete = existingList.stream()
                    .filter(existing -> list.stream().noneMatch(newItem -> Objects.equals(newItem.getId(), existing.getId())))
                    .collect(Collectors.toList());

            // 2. 找出需要更新的记录（ID匹配但内容不同）
            List<RtCertFiledCustomerDO> toUpdate = list.stream()
                    .filter(item -> item.getId() != null && existingIds.contains(item.getId().toString()))
                    .collect(Collectors.toList());

            // 3. 找出需要新增的记录（ID为null或不在数据库中）
            List<RtCertFiledCustomerDO> toInsert = list.stream()
                    .filter(item -> item.getId() == null || !existingIds.contains(item.getId().toString()))
                    .collect(Collectors.toList());

            // 执行操作
            if (Boolean.FALSE.equals(formDTO.getEditWithoutDelete())) {
                toDelete.forEach(item -> deleteRtCertFiledCustomerById(item.getId()));
            }
              toUpdate.forEach(item -> {
                item.setFiledId(formDTO.getRtCertFiledDO().getId() );
                item.setCtype(formDTO.getRtCertFiledDO().getCtype());
                item.setModel(formDTO.getRtCertFiledDO().getModel());
                updateRtCertFiledCustomer(item);
            });
            toInsert.forEach(item -> {
                item.setFiledId(formDTO.getRtCertFiledDO().getId());
                item.setCtype(formDTO.getRtCertFiledDO().getCtype());
                item.setModel(formDTO.getRtCertFiledDO().getModel());
                insertRtCertFiledCustomer(item);
            });
        }
    }

    @Override
    public int deleteRtCertFiledCustomerByIds(List<String> ids) {
        return rtCertFiledCustomerMapper.deleteRtCertFiledCustomerByIds(ids);
    }

    @Override
    public int deleteRtCertFiledCustomerById(String id) {
        return rtCertFiledCustomerMapper.deleteRtCertFiledCustomerById(id);
    }

    @Override
    public int deleteRtCertFiledCustomerByFiledId(String id) {
        return rtCertFiledCustomerMapper.deleteRtCertFiledCustomerByFiledId(id);
    }

    @Override
    public RtCertFiledCustomerDO selectRtCertFiledCustomerByDO(RtCertFiledCustomerDO rtCertFiledCustomer){
        List<RtCertFiledCustomerDO> list = rtCertFiledCustomerMapper.selectRtCertFiledCustomerList(rtCertFiledCustomer);
        if(list.isEmpty()){
            return null;
        }
        return list.get(0);
    }
}